package fr.ttalbot.flex.components
{
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;
	import flash.utils.Timer;
	
	import mx.collections.ArrayCollection;
	import mx.containers.Canvas;
	import mx.containers.VBox;
	import mx.controls.Alert;
	import mx.controls.Image;
	import mx.controls.Label;
	import mx.effects.Fade;
	import mx.effects.Move;
	import mx.events.EffectEvent;

	[Bindable]
	
	/**
	 * This components diplay photos one by one. 
	 * 
	 * @author Thomas TALBOT
	 * 
	 */	
	public class Slider extends Canvas
	{
		public static const PIC_CHANGING_EVENT: String = "picChangingEvent";
		public static const PIC_CHANGED_EVENT: String = "picChangedEvent";
		
		private static const PROP: int = 5;
		
		private var __pics: ArrayCollection;
		private var __dataProvider: XML;
		private var __path: String = "";
		private var __duration: int = 5;
		private var __timer: Timer;
		private var __currentIndex: int = 0;
		private var __descContainer: VBox;
		private var __title: Label;
		private var __desc: Label;
		private var __useDescription: Boolean;
		
		
		
		// ================================================================= //
		// ========================= CONSTRUCTOR =========================== //
		// ================================================================= //
		
		/**
		 * 
		 */
		public function Slider() {
			super();
			useDescription = false;
			verticalScrollPolicy = "off";
			horizontalScrollPolicy = "off";
		}
		
		/**
		 * 
		 */
		override protected function createChildren(): void {
			super.createChildren();
			__pics = new ArrayCollection();
			createTimer();
			createPics();
		}
		
		
		// ================================================================= //
		// ====================== PRIVATE FUNCTIONS ======================== //
		// ================================================================= //
		
		private function createTimer(): void {
			__timer = new Timer(__duration*1000);
			__timer.addEventListener(TimerEvent.TIMER, changePic);
		}
		
		/**
		 * 
		 */
		private function createDescContainer(): void {
			__descContainer = new VBox();
			__title = new Label();
			__desc = new Label();
			__descContainer.alpha = 0.6;
			__descContainer.width = 100//this.width;
			__descContainer.height = 100//this.height / PROP;
			__descContainer.setStyle("backgroundColor", 0x000000);
			__descContainer.y = (this.height/PROP)*(PROP-1);
			__title.setStyle("color", 0xFFFFFF);
			__desc.setStyle("color", 0xFFFFFF);
			__title.setStyle("fontWeight", "bold");
			__title.setStyle("fontSize", "22");
			__descContainer.addChild(__title);
			__descContainer.addChild(__desc);
			addEventListener(PIC_CHANGING_EVENT, hideDesc);
			addEventListener(PIC_CHANGED_EVENT, showDesc);
			this.addChild(__descContainer);
		}
		
		/**
		 * 
		 */
		private function createPics(): void {
			__pics.removeAll();
			if (dataProvider) {
				__path = String(dataProvider.@path);
				
				for each (var pic : XML in dataProvider.pic) {
					var content: Loader = new Loader();
					content.contentLoaderInfo.addEventListener(Event.COMPLETE, handle_loadComplete);
					content.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, handle_loadError);
					content.load(new URLRequest(__path + pic.@name));
					/* if (String(pic.link).search("http://") == 0) {
						addCapabilities(img, pic);
					} */
					//__pics.addItem(content);
					//this.addChildAt(img, 0);
				}
				__timer.start();
			}
		}
		
		/**
		 * 
		 */
		private function addCapabilities(img: Image, pic: XML): void {
			img.buttonMode = true;
			img.useHandCursor = true;
			img.addEventListener(MouseEvent.CLICK, handle_imgClick);
			img.toolTip = dataProvider.pic[__currentIndex].description;
		}
		
		/**
		 * 
		 */
		private function hideDesc(event: Event): void {
			var effect: Move= new Move();
			effect.target = __descContainer;
			effect.yBy = __descContainer.height;
			//effect.addEventListener(EffectEvent.EFFECT_END, onEffectEnd);
			effect.play();
		}
		
		/**
		 * 
		 */
		private function showDesc(event: Event): void {
			var effect: Move = new Move();
			effect.target = __descContainer;
			effect.yBy = -(__descContainer.height);
			effect.play();
		}
		
		/**
		 * 
		 */
		private function changePic(event: TimerEvent): void {
			var effect: Fade = new Fade();
			this.dispatchEvent(new Event(PIC_CHANGING_EVENT));
			effect.addEventListener(EffectEvent.EFFECT_END, onEffectEnd);
			effect.target = __pics.getItemAt(__currentIndex);
			effect.alphaFrom = 1;
			effect.alphaTo = 0;
			effect.play();
		}
		
		/**
		 * 
		 */
		private function onEffectEnd(event: EffectEvent): void {
			this.rawChildren.setChildIndex(__pics.getItemAt(__currentIndex) as DisplayObject, 0);
			Loader(__pics.getItemAt(__currentIndex)).alpha = 1;
			__currentIndex = (__currentIndex + 1)%__pics.length;
			//__title.text = dataProvider.pic[__currentIndex].title;
			//__desc.text = dataProvider.pic[__currentIndex].description;
			dispatchEvent(new Event(PIC_CHANGED_EVENT));
		}
		
		/**
		 * 
		 */
		private function handle_imgClick(event: MouseEvent): void {
			var url: URLRequest = new URLRequest(dataProvider.pic[__currentIndex].link);
			navigateToURL(url);
		}
		
		private function handle_loadComplete(event: Event): void {
			rawChildren.addChildAt(event.target.loader, 0);
			__pics.addItem(event.target.loader);
		}
		
		private function handle_loadError(event: IOErrorEvent): void {
			Alert.show(event.text, "Error");
		}
		
		
		// ================================================================= //
		// ====================== GETTERS / SETTERS ======================== //
		// ================================================================= //
		
		/**
		 * 
		 */
		[Inspectable(type="String")]
		public function get dataProvider(): XML {
			return __dataProvider;
		}
		public function set dataProvider(anXML: XML): void {
			__dataProvider = anXML;
			createPics();
			invalidateProperties();
		}
		
		/**
		 * 
		 */
		[Inspectable(type="Number", defaultValue=5)]
		public function get duration(): int {
			return __duration;
		}
		public function set duration(anInt: int): void {
			__duration = anInt;
			invalidateProperties();
		}
		
		/**
		 * 
		 */
		[Inspectable(type="Boolean", defaultValue=false)]
		public function get useDescription(): Boolean {
			return __useDescription;
		}
		public function set useDescription(aBool: Boolean): void {
			__useDescription = aBool;
			if (__useDescription) {
				createDescContainer();
			}
			invalidateProperties();
		}
		
	}
}